﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Medianamik.Core;
using Medianamik.Core.DAL;
using Medianamik.Core.DAL.Repositories;
using Medianamik.Core.DAL.Services;
using Medianamik.Core.Interfaces;
using SubSonic;

namespace Medianamik.Client.Data.Repositories
{
    public class MedianamikDTOWithNameRepository : IMedianamikRepository<IMedianamikDTOWithName>
    {
        private readonly IBaseTypeRepository _baseTypeRepository;

        public MedianamikDTOWithNameRepository(IBaseTypeRepository baseTypeNodeRepository)
        {
            _baseTypeRepository = baseTypeNodeRepository;
        }

        public void SaveNodes(IEnumerable<Node> nodes)
        {
            _baseTypeRepository.SaveNodes(nodes);
        }

        public IBaseTypeRepository BaseTypeNodeRepository
        {
            get { return _baseTypeRepository; }
        }

        public IMedianamikDTOWithName Get(Guid nodeId)
        {
            return BaseTypeNodeRepository.Get(nodeId);
        }

        public IMedianamikDTOWithName Get(Guid nodeId, CultureInfo culture, ContentState contentState)
        {
            return BaseTypeNodeRepository.Get(nodeId, culture, contentState);
        }

        public IMedianamikDTOWithName Get(Guid nodeId, CultureInfo culture,
            ContentState contentState, ActiveStatus activeStatus)
        {
            return BaseTypeNodeRepository.Get(nodeId, culture, contentState, activeStatus);
        }

        public IList<IMedianamikDTOWithName> GetWithFilters(Guid? typeId, Guid? parentId,
            IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd,
            string orderByString, int? depth, bool withTypeInheritance)
        {
            return BaseTypeNodeRepository
                .GetWithFilters(typeId, parentId, wheres, betweensAnd, orderByString, depth,
                                withTypeInheritance)
                .Cast<IMedianamikDTOWithName>()
                .ToList();
        }

        public PagedCollection<IMedianamikDTOWithName> PagedWithFilters(int pageIndex,
            int pageSize, Guid? typeId, Guid? parentId, IEnumerable<Where> wheres,
            IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            var collection = BaseTypeNodeRepository
                .PagedWithFilters(pageIndex, pageSize, typeId, parentId, wheres, betweensAnd,
                                  orderByString, depth, withTypeInheritance);

            return new PagedCollection<IMedianamikDTOWithName>(
                collection.Collection.Cast<IMedianamikDTOWithName>(),
                collection.TotalCount);
        }

        public IList<IMedianamikDTOWithName> ChildsOf(Guid nodeId, bool inclusive, int maxDepth)
        {
            return BaseTypeNodeRepository.ChildsOf(nodeId, inclusive, maxDepth)
                .Cast<IMedianamikDTOWithName>().ToList();
        }

        public IList<IMedianamikDTOWithName> ParentsOf(Guid nodeId, bool inclusive, int maxDepth)
        {
            return BaseTypeNodeRepository.ParentsOf(nodeId, inclusive, maxDepth)
                .Cast<IMedianamikDTOWithName>().ToList();
        }

        public IEnumerable<IMedianamikDTOWithName> LoadByIDs(string ids)
        {
            return BaseTypeNodeRepository.LoadByIDs(ids)
                .Cast<IMedianamikDTOWithName>();
        }

        public IEnumerable<IMedianamikDTOWithName> LoadByIDs(IList<Guid> ids)
        {
            return BaseTypeNodeRepository.LoadByIDs(ids)
                .Cast<IMedianamikDTOWithName>();
        }

        public IList<IMedianamikDTOWithName> All()
        {
            return BaseTypeNodeRepository.All()
                .Cast<IMedianamikDTOWithName>()
                .ToList();
        }

        public IList<IMedianamikDTOWithName> GetWithFilters(CultureInfo culture,
            ContentState contentState, ActiveStatus status, Guid? typeId, Guid? parentId,
            IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd,
            string orderByString, int? depth, bool withTypeInheritance)
        {
            return BaseTypeNodeRepository.GetWithFilters(culture, contentState, status, typeId,
                         parentId, wheres, betweensAnd, orderByString, depth,
                         withTypeInheritance).Cast<IMedianamikDTOWithName>().ToList();
        }

        public IList<IMedianamikDTOWithName> GetWithFilters(bool multiLingual,
            CultureInfo culture, ActiveStatus status, Guid? typeId,
            Guid? parentId, DateTime? startDate, DateTime? endDate,
            string keywords, string orderBy, IEnumerable<Where> additionalWheres,
            bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public IList<IMedianamikDTOWithName> AllInstances()
        {
            return BaseTypeNodeRepository.AllInstances().Cast<IMedianamikDTOWithName>().ToList();
        }

        public IList<IMedianamikDTOWithName> AllInstances(ContentState contentState, ActiveStatus status)
        {
            return BaseTypeNodeRepository.AllInstances(contentState, status).Cast<IMedianamikDTOWithName>().ToList();
        }

        public IList<IMedianamikDTOWithName> AllInstances(Guid nodeId)
        {
            throw new NotImplementedException();
        }

        public IList<IMedianamikDTOWithName> AllInstances(Guid nodeId, ContentState contentState, ActiveStatus status)
        {
            throw new NotImplementedException();
        }

        public IList<IMedianamikDTOWithName> AlllInstancesWithFilters(ContentState contentState, ActiveStatus status, Guid? typeId, Guid? parentId, IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public IList<IMedianamikDTOWithName> AlllInstancesWithFilters(Guid? typeId, Guid? parentId, IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public PagedCollection<IMedianamikDTOWithName> PagedWithFilters(CultureInfo culture,
            ContentState contentState, ActiveStatus status, int pageIndex, int pageSize,
            Guid? typeId, Guid? parentId, IEnumerable<Where> wheres,
            IEnumerable<BetweenAnd> betweensAnd, string orderByString,
            int? depth, bool withTypeInheritance)
        {
            var collection = BaseTypeNodeRepository.PagedWithFilters(culture,
                contentState, status, pageIndex, pageSize, typeId, parentId, wheres,
                betweensAnd, orderByString, depth, withTypeInheritance);

            return new PagedCollection<IMedianamikDTOWithName>(
                collection.Collection.Cast<IMedianamikDTOWithName>(),
                collection.TotalCount);

        }

        public PagedCollection<IMedianamikDTOWithName> PagedWithFilters(bool multiLingual,
            CultureInfo culture, ContentState contentState, ActiveStatus status, int pageIndex,
            int pageSize, Guid? typeId, Guid? parentId, IEnumerable<Where> wheres,
            IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            var collection = BaseTypeNodeRepository.PagedWithFilters(multiLingual, culture, contentState, status,
                                                                     pageIndex, pageSize, typeId, parentId, wheres,
                                                                     betweensAnd, orderByString, depth,
                                                                     withTypeInheritance);

            return new PagedCollection<IMedianamikDTOWithName>(
                collection.Collection.Cast<IMedianamikDTOWithName>(),
                collection.TotalCount);
        }

        public IList<IMedianamikDTOWithName> ChildsOf(Guid nodeId, bool inclusive,
            int maxDepth, CultureInfo culture, ContentState contentState, ActiveStatus status)
        {
            return BaseTypeNodeRepository.ChildsOf(nodeId, inclusive, maxDepth, culture, contentState, status)
                .Cast<IMedianamikDTOWithName>().ToList();
        }

        public IList<IMedianamikDTOWithName> ParentsOf(Guid nodeId, bool inclusive,
            int maxDepth, CultureInfo culture, ContentState contentState, ActiveStatus status)
        {
            return BaseTypeNodeRepository.ParentsOf(nodeId, inclusive, maxDepth, culture,
                                                    contentState, status).Cast<IMedianamikDTOWithName>().ToList();
        }

        public IEnumerable<IMedianamikDTOWithName> LoadByIDs(string ids, string cultureName,
            ContentState contentState, ActiveStatus status)
        {
            return BaseTypeNodeRepository.LoadByIDs(ids, cultureName, contentState, status)
                .Cast<IMedianamikDTOWithName>();
        }

        public IEnumerable<IMedianamikDTOWithName> LoadByIDs(IList<Guid> ids, string cultureName,
            ContentState contentState, ActiveStatus status)
        {
            return BaseTypeNodeRepository.LoadByIDs(ids, cultureName, contentState, status)
                .Cast<IMedianamikDTOWithName>();
        }

        public IList<IMedianamikDTOWithName> All(CultureInfo culture, ContentState contentState,
                                                 ActiveStatus status)
        {
            return BaseTypeNodeRepository.All(culture, contentState, status)
                .Cast<IMedianamikDTOWithName>().ToList();
        }

        public void DeleteByParent(Guid parendId, bool destroy)
        {
            BaseTypeNodeRepository.DeleteByParent(parendId, true);
        }

        public void DeleteBranch(Guid nodeId, bool destroy)
        {
            BaseTypeNodeRepository.DeleteBranch(nodeId, destroy);
        }

        public void Delete(IMedianamikDTOWithName item)
        {
            BaseTypeNodeRepository.Delete(item.NodeId, false);
        }

        #region Map And Save

        public void MapAndSaveItem<T>(T item, MappingOptions options) where T : IMedianamikDTO
        {
            BaseTypeNodeRepository.MapAndSaveItem(item, options);
        }
        public void MapAndSaveItem<T>(T item) where T : IMedianamikDTO
        {
            MapAndSaveItem(item, MappingOptions.DefaultOptions);
        }

        public void MapAndSaveItems<T>(IEnumerable<T> items, MappingOptions options) where T : IMedianamikDTO
        {
            BaseTypeNodeRepository.MapAndSaveItems(items, options);
        }
        public void MapAndSaveItems<T>(IEnumerable<T> items) where T : IMedianamikDTO
        {
            MapAndSaveItems(items, MappingOptions.DefaultOptions);
        }

        public void MapAndPublishItem<T>(T item, MappingOptions options) where T : IMedianamikDTO
        {
            MapAndPublishItem(item, options);
        }
        public void MapAndPublishItem<T>(T item) where T : IMedianamikDTO
        {
            MapAndPublishItem(item, MappingOptions.DefaultOptions);
        }

        public void MapAndPublishItems<T>(IEnumerable<T> items, MappingOptions options) where T : IMedianamikDTO
        {
            BaseTypeNodeRepository.MapAndPublishItems(items, options);
        }
        public void MapAndPublishItems<T>(IEnumerable<T> items) where T : IMedianamikDTO
        {
            MapAndPublishItems(items, MappingOptions.DefaultOptions);
        }

        #endregion

        public void Delete(Guid nodeId, bool destroy)
        {
            throw new NotImplementedException();
        }

        public void Reorder(Guid id, Guid destinationId, DropPosition position)
        {
            BaseTypeNodeRepository.Reorder(id, destinationId, position);
        }

        public PagedCollection<IMedianamikDTOWithName> PagedWithFilters(CultureInfo editionCulture,
            int pageIndex, int pageSize, Guid baseTypeId, Guid moduleNodeId,
            IEnumerable<Where> additionalWheres)
        {
            var collection = BaseTypeNodeRepository.PagedWithFilters(editionCulture, pageIndex, pageSize, baseTypeId, moduleNodeId,
                                                           additionalWheres);
            return new PagedCollection<IMedianamikDTOWithName>(
                collection.Collection.Cast<IMedianamikDTOWithName>(),
                collection.TotalCount);
        }

        public void SetActiveStatus(Guid id, CultureInfo culture, ActiveStatus status)
        {
            BaseTypeNodeRepository.SetActiveStatus(id, culture, status);
        }

        public INodeWrapper NewNode(IMedianamikDTO dto)
        {
            return BaseTypeNodeRepository.NewNode(dto);
        }

        public INodeWrapper NewNode(IMedianamikDTO dto, bool validateHierarchicalRules)
        {
            return BaseTypeNodeRepository.NewNode(dto, validateHierarchicalRules);
        }

        public INodeWrapper GetExistingNode(IMedianamikDTO dto)
        {
            return BaseTypeNodeRepository.GetExistingNode(dto);
        }

        public void SaveNode(INodeWrapper node)
        {
            BaseTypeNodeRepository.SaveNode(node);
        }

        public void PublishNode(INodeWrapper node, CultureInfo culture)
        {
            BaseTypeNodeRepository.PublishNode(node, culture);
        }

        public void SaveNodeHandlingPositionAndParentNodeId(INodeWrapper node,
            Guid? parentNodeId, short? position)
        {
            BaseTypeNodeRepository.SaveNodeHandlingPositionAndParentNodeId(node, parentNodeId, position);
        }

        public void PublishNodeHandlingPositionAndParentNodeId(INodeWrapper node,
              Guid? parentNodeId, short? position, CultureInfo culture)
        {
            BaseTypeNodeRepository.PublishNodeHandlingPositionAndParentNodeId(node,
                parentNodeId, position, culture);
        }

        public INodeMapper NodeMapper
        {
            get { return BaseTypeNodeRepository.NodeMapper; }
        }

        public ICultureService CultureService
        {
            get { return BaseTypeNodeRepository.CultureService; }
        }

        public IContentStateService ContentStateService
        {
            get { return BaseTypeNodeRepository.ContentStateService; }
        }

        public PagedCollection<IMedianamikDTOWithName> PagedWithFilters(CultureInfo editionCulture,
            int pageIndex, int pageSize, ActiveStatus contentStatus, Guid? baseTypeId,
            Guid? moduleNodeId, DateTime? startDate, DateTime? endDate, string keywords, string orderBy,
            IEnumerable<Where> additionalWheres, bool withTypeInheritance)
        {
            var collection = BaseTypeNodeRepository.PagedWithFilters(editionCulture, pageSize, pageSize,
                                                                     contentStatus, baseTypeId, moduleNodeId, startDate,
                                                                     endDate, keywords, orderBy, additionalWheres,
                                                                     withTypeInheritance);
            return new PagedCollection<IMedianamikDTOWithName>(
                collection.Collection.Cast<IMedianamikDTOWithName>(),
                collection.TotalCount);
        }

        public PagedCollection<IMedianamikDTOWithName> PagedWithFilters(bool multiLingual,
            CultureInfo editionCulture, int pageIndex, int pageSize, ActiveStatus contentStatus,
            Guid? baseTypeId, Guid? moduleNodeId, DateTime? startDate, DateTime? endDate,
            string keywords, string orderBy, IEnumerable<Where> additionalWheres,
            IEnumerable<BetweenAnd> additionalBetweenAnds, bool withTypeInheritance)
        {
            var collection = BaseTypeNodeRepository.PagedWithFilters(multiLingual, editionCulture,
                pageIndex, pageSize,
                 contentStatus, baseTypeId, moduleNodeId, startDate,
                 endDate, keywords, orderBy, additionalWheres, additionalBetweenAnds,
                 withTypeInheritance);

            return new PagedCollection<IMedianamikDTOWithName>(
                collection.Collection.Cast<IMedianamikDTOWithName>(),
                collection.TotalCount);
        }
    }
}
